<?php

namespace App\Service\User;

use App\Cache\RedisKey;
use App\Constants\ErrorCode;
use App\Constants\UserUpdateProfileCode;
use App\Helpers\AliyunUtil;
use App\Helpers\RedisUtil;
use App\Helpers\RongCloud;
use App\Model\Act\ProfileRewardLog;
use App\Model\BlackWords;
use App\Model\Moment;
use App\Model\ProfileVerifyLog;
use App\Model\Service\NewGirlReplyPackageService;
use App\Model\User;
use App\Model\UserActLog;
use App\Model\UserAvatarLog;
use App\Model\UserProfile;
use App\Model\UserProfilePersonal;
use App\Service\BaseService;

use function GuzzleHttp\json_encode;

/**
 * 用户资料编辑
 */
class ProfileModifyService extends BaseService
{
    //修改字段
    public $modifyFields = ['poster', 'nick_name', 'city', 'self_intro', 'birthday', 'skills', 'voice_link', 'voice_duration'];

    public function handle()
    {
        //同步到动态
        $this->syncMoment = intval($this->request->input('sync_moment', 0));
        $userId = $this->getUserId();
        $allPost = $this->request->all();
        $result = $this->checkValid($allPost);
        if ($result['errcode']) {
            return $this->setError($result['errcode'], $result['errmsg']);
        }

        //老资料
        $oldProfile = UserProfile::getProfile($userId);

        $updateInfo = $this->filterFields($allPost);
        //新版本不更新poster
        if (isset($updateInfo['poster']) && $updateInfo['poster']) {
            if($oldProfile['is_lock'] == 1){
                return $this->setError(0, '请联系客服解开头像上传状态！');
            }
            //真人认证标识
            $posters = explode(',', $updateInfo['poster']);
            $avatarVrfy = UserProfilePersonal::compareRealFacepic($userId, $posters[0]);

            if ($oldProfile->gender == 0) {
                $role = $avatarVrfy == 1 ? UserProfile::ROLE_HOST : UserProfile::ROLE_USER;
                UserProfile::where('user_id', $userId)->limit(1)->update(['avatar_vrfy' => $avatarVrfy, 'role' => $role, 'is_lock' => 1]);
            } else {
                UserProfile::where('user_id', $userId)->limit(1)->update(['avatar_vrfy' => $avatarVrfy, 'is_lock' => 1]);
            }

            unset($updateInfo['poster']);
        }

        if (isset($updateInfo['nick_name']) && $updateInfo['nick_name']) {
            if (!$this->checkUpdateUserProfileLimit($userId)) {
                return $this->setError(0, '当日修改次数已达上限！');
            }
        }

        if (isset($updateInfo['self_intro']) && $updateInfo['self_intro']) {
            if (!$this->checkUpdateUserProfileLimit($userId, 'intro')) {
                return $this->setError(0, '当日修改次数已达上限！');
            }
        }

        //更新资料
        $result = UserProfile::updateInfo($userId, $updateInfo);
        //修改回调
        isset($allPost['poster']) && $updateInfo['poster'] = $allPost['poster'];
        $this->modifyCallback($userId, $updateInfo, $this->getUser(), $oldProfile);

        $newGirlTaskValid = config('act.new_girl_task_valid', '2023-03-12');
        if ($oldProfile->gender == 0 && $oldProfile->created_at >= $newGirlTaskValid) {
            NewGirlReplyPackageService::checkFinishUserInfo((int)$userId);
        }

        return ['result' => $result ? 1 : 0];
    }

    /**
     * 检测输入违法
     */
    function checkValid($postData = [])
    {
        $content = [];
        if (isset($postData['nick_name']) && $postData['nick_name']) $content[] = $postData['nick_name'];
        if (isset($postData['self_intro']) && $postData['self_intro']) $content[] = $postData['self_intro'];

        foreach ($content as $cont) {
            $check = BlackWords::checkLegal($cont);
            if ($check['result'] != 1) {
                return ['errcode' => ErrorCode::INPUT_SENSITIVE, 'errmsg' => '输入违规，请重新输入～'];
            }
        }
        return ['errcode' => 0];
    }

    /**
     * 过滤更新资料的字段信息
     */
    function filterFields($allPost = [])
    {
        $info = [];
        foreach ($this->modifyFields as $field) {
            if (isset($allPost[$field]) && $allPost[$field] !== '') {
                if ($field == 'voice_link') $info['voice']['link'] = $allPost[$field];
                elseif ($field == 'voice_duration') $info['voice']['duration'] = $allPost[$field];
                else $info[$field] = $allPost[$field];
            }
        }
        isset($info['voice']) && $info['voice'] = json_encode($info['voice']);
        return $info;
    }

    /**
     * 修改字段回调
     */
    function modifyCallback($userId = 0, $updateInfo = [], $user = null, $oldProfile = null)
    {
        //昵称修改
        if (isset($updateInfo['nick_name']) && $updateInfo['nick_name']) {
            $profile = UserProfile::getProfile($userId);
            User::updateIMInfo($user->im_account, $updateInfo['nick_name']);
            $ret = UserProfile::updateRongCloudInfo($user->im_account, $profile['nick_name'], AliyunUtil::imageResize(AliyunUtil::IMG_HOST . $profile['avatar'], 200, 200));
            log_info(__CLASS__ . "==modifyName=={$userId}=={$profile['nick_name']}=={$profile['avatar']}==" . json_encode($ret));

            ProfileVerifyLog::addRecord($userId, ProfileVerifyLog::TYPE_NICKNAME, $updateInfo['nick_name']);

            RedisUtil::addUpdateProfileLock($userId);
        }

        //修改海报和头像
        if (isset($updateInfo['poster']) && $updateInfo['poster']) {
            $posters = explode(',', $updateInfo['poster']);
            $avatar = $posters[0];
            $profile = UserProfile::getProfile($userId);
            $ret = UserProfile::updateRongCloudInfo($user->im_account, $profile['nick_name'], AliyunUtil::imageResize(AliyunUtil::IMG_HOST . $avatar, 200, 200));

            //行为日志（女：先发后审，男：先审后发）
            $avatarStatus = UserActLog::FLAG_OK; //UserActLog::FLAG_OK;
            //$profile->gender == 0 ? UserActLog::FLAG_OK : UserActLog::FLAG_ING;

            UserProfile::updateInfo($userId, ['avatar' => $avatar]);

//            UserActLog::addRecord($userId, UserActLog::ACT_AVATAR, $avatar, $avatarStatus);
            UserAvatarLog::addRecord($userId, $avatar, $avatarStatus);

            //奖励
            ProfileRewardLog::doReward($userId, 'avatar', 3);
            log_info(__CLASS__ . "==modifyAvatar=={$userId}=={$profile['nick_name']}=={$profile['avatar']}==" . json_encode($ret));
        }

        //爱情宣言
        if (isset($updateInfo['self_intro']) && $updateInfo['self_intro']) {
            ProfileVerifyLog::addRecord($userId, ProfileVerifyLog::TYPE_SELF_INTRO, $updateInfo['self_intro']);
            //奖励
            !$oldProfile->self_intro && ProfileRewardLog::doReward($userId, 'self_intro', 2);

            RedisUtil::addUpdateProfileLock($userId, 'intro');

            //是否发布到动态
            if ($this->syncMoment) {
                Moment::create([
                    'user_id' => $userId,
                    'user_gender' => $oldProfile->gender,
                    'words' => $updateInfo['self_intro'],
                    'status' => Moment::STATUS_VERIFING,
                    'moment_type' => Moment::TYPE_SELF_INTRO,
                ]);
            }
        }

        if (isset($updateInfo['voice']) && $updateInfo['voice']) {
            $info = json_decode($updateInfo['voice'], true);
            ProfileVerifyLog::addRecord($userId, ProfileVerifyLog::TYPE_VOICE, $info['link']);
            //奖励
            !$oldProfile->voice && ProfileRewardLog::doReward($userId, 'voice', 2);
        }

        if (isset($updateInfo['city']) && $updateInfo['city']) {
            !$oldProfile->city && ProfileRewardLog::doReward($userId, 'profile', 2);
        }
    }

    /**
     * 检查修改资料限制次数限制
     * @param $userId
     * @param $type
     * @return bool
     */
    function checkUpdateUserProfileLimit($userId, $type = 'nickname')
    {
        $redis = RedisUtil::getRedis('cache');

        $redisKey = RedisKey::operationUserProfileByNicknameLock($userId);
        $maxLimit = UserUpdateProfileCode::UPDATE_INTRO_MAX;
        if ($type == 'intro') {
            $redisKey = RedisKey::operationUserProfileByIntroLock($userId);
            $maxLimit = UserUpdateProfileCode::UPDATE_NICKNAME_MAX;
        }

        if ($redis->get($redisKey) >= $maxLimit) {
            return false;
        }

        return true;
    }
}
